@page "/visitor/preregisters"


@using Blazor.Server.UI.Services
@using Blazor.Server.UI.Pages.CheckinPoints
@using CleanArchitecture.Blazor.Application.Features.SiteConfigurations.Queries.GetAll
@using CleanArchitecture.Blazor.Application.Features.VisitorHistories.DTOs
@using CleanArchitecture.Blazor.Application.Features.VisitorHistories.Queries.GetAll
@using CleanArchitecture.Blazor.Application.Features.Visitors.Commands.Create
@using CleanArchitecture.Blazor.Application.Features.Visitors.Commands.Delete
@using CleanArchitecture.Blazor.Application.Features.Visitors.DTOs
@using CleanArchitecture.Blazor.Application.Features.Visitors.Queries.Pagination
@using CleanArchitecture.Blazor.Application.Features.Visitors.Commands.AddEdit
@using CleanArchitecture.Blazor.Application.Features.Visitors.Queries.Search
@using HashidsNet
@using Net.Codecrete.QrCodeGenerator
@using SixLabors.ImageSharp
@using SixLabors.ImageSharp.Formats
@using SixLabors.ImageSharp.Processing
@inject IJSRuntime JS
@inject IStringLocalizer<Visitors> L
@attribute [Authorize(Policy = Permissions.Visitors.PreRegisters)]
<PageTitle>@Title</PageTitle>
<style>
    .mud-table-toolbar {
        height: 84px !important;
    }
</style>
<ErrorBoundary>
    <ChildContent>
        <MudGrid>
            <MudItem xs="12" sm="7">
                <MudPaper Class="pa-4 mt-4">
                    <MudTextField @bind-Value="_searchString" Label="@L["Search for visitor's email or phone number."]" Variant="Variant.Outlined" Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Search" AdornmentColor="MudBlazor.Color.Primary" OnAdornmentClick="OnSearch" />
                </MudPaper>
                <MudPaper Class="pa-4 mt-4">
                    <MudForm Model="model" @ref="form" Validation="@(modelValidator.ValidateValue)">
                        <MudGrid>
                            <MudItem xs="12" sm="6" md="4">
                                <MudTextField Label="@L["Visitor's Name"]" @bind-Value="model.Name"
                                              For="@(() => model.Name)"
                                              Disabled="@(model.Apppoved==true)"
                                              Required="true"
                                              RequiredError="@L["product name is required!"]">
                                </MudTextField>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="8">
                                <MudTextField Label="@L["Company Name"]"
                                              For="@(() => model.CompanyName)"
                                              Disabled="@(model.Apppoved==true)"
                                              @bind-Value="model.CompanyName"></MudTextField>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <MudTextField Label="@L["License Plate Number"]"
                                              For="@(() => model.LicensePlateNumber)"
                                              Disabled="@(model.Apppoved==true)"
                                              @bind-Value="model.LicensePlateNumber"></MudTextField>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <MudTextField Label="@L["Email"]"
                                              For="@(() => model.Email)"
                                              Disabled="@(model.Apppoved==true)"
                                              @bind-Value="model.Email"></MudTextField>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <MudTextField Label="@L["Phone Number"]"
                                              For="@(() => model.PhoneNumber)"
                                              Disabled="@(model.Apppoved==true)"
                                              Required="true"
                                              RequiredError="@L["Phone Number is required!"]"
                                              @bind-Value="model.PhoneNumber"></MudTextField>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <MudTextField Label="@L["Identification No."]"
                                              For="@(() => model.IdentificationNo)"
                                              Disabled="@(model.Apppoved==true)"
                                              Required="true"
                                              RequiredError="@L["Identification No. is required!"]"
                                              @bind-Value="model.IdentificationNo"></MudTextField>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <PicklistAutocomplete Picklist="Picklist.Gender"
                                                      Disabled="@(model.Apppoved==true)"
                                                      Label="@L["Gender"]"
                                                      For="@(() => model.Gender)"
                                                      ResetValueOnEmptyText="true"
                                                      @bind-Value="model.Gender"></PicklistAutocomplete>
                            </MudItem>

                            <MudItem xs="12" sm="6" md="4">
                                <PicklistAutocomplete Picklist="Picklist.Purpose"
                                                      Label="@L["Purpose"]"
                                                      Disabled="@(model.Apppoved==true)"
                                                      Required="true"
                                                      RequiredError="@L["purpose is required!"]"
                                                      For="@(() => model.Purpose)"
                                                      ResetValueOnEmptyText="true"
                                                      @bind-Value="model.Purpose"></PicklistAutocomplete>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <EmployeeAutocomplete Label="@L["Select Employee"]"
                                                      Required="true"
                                                      Disabled="@(model.Apppoved==true)"
                                                      RequiredError="@L["employee is required!"]"
                                                      For="@(() => model.EmployeeId)"
                                                      ResetValueOnEmptyText="true"
                                                      @bind-Value="model.EmployeeId"></EmployeeAutocomplete>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <MudDatePicker Label="@L["Expected Date"]"
                                               Disabled="@(model.Apppoved==true)"
                                               Required="true"
                                               RequiredError="@L["expected date is required!"]"
                                               For="@(() => model.ExpectedDate)"
                                               @bind-Date="model.ExpectedDate"></MudDatePicker>
                            </MudItem>
                            <MudItem xs="12" sm="6" md="4">
                                <MudTimePicker Label="@L["Expected Time"]"
                                               Required="true"
                                               Disabled="@(model.Apppoved==true)"
                                               RequiredError="@L["expected time is required!"]"
                                               AmPm="true" TimeFormat="h:mm tt"
                                               For="@(() => model.ExpectedTime)"
                                               @bind-Time="model.ExpectedTime"></MudTimePicker>
                            </MudItem>
                            <MudItem xs="12" sm="12">
                                <Blazor.Server.UI.Pages.Sites.SiteWithAddressAutocomplete Label="@L["Select Site - Address"]"
                                                  Disabled="@(model.Apppoved==true)"
                                                  For="@(() => model.SiteId)"
                                                  Required="true" RequiredError="@L["site - address is required!"]"
                                                  @bind-Value="model.SiteId">
                                </Blazor.Server.UI.Pages.Sites.SiteWithAddressAutocomplete>
                            </MudItem>
                            <MudItem xs="12" sm="12">
                                <MudTextField Label="@L["Comment"]"
                                              For="@(() => model.Comment)"
                                              Lines="2"
                                              Disabled="@(model.Apppoved==true)"
                                              @bind-Value="model.Comment"></MudTextField>
                            </MudItem>


                            @* <MudItem xs="12" sm="6" md="4">
                                <MudCheckBox Label="@L["Has apppoved"]"
                                Disabled="@(model.Apppoved==true)"
                                For="@(() => model.Apppoved)" ReadOnly="true"
                                @bind-Checked="model.Apppoved"></MudCheckBox>
                                </MudItem>
                                <MudItem xs="12" sm="6" md="8">
                                <MudTextField Label="@L["Approval Outcome"]"
                                Disabled="@(model.Apppoved==true)"
                                For="@(() => model.ApprovalOutcome)"
                                @bind-Value="model.ApprovalOutcome"></MudTextField>
                                </MudItem>*@
                            <MudItem xs="12" sm="12" md="12">
                                <div class="d-flex flex-nowrap  overflow-auto pa-4">
                                    <div class="d-flex flex-nowrap gap-4" style="max-width:680px">
                                        <UploadPhotoComponent Desciption="@L["Only green codes are allowed"]"
                                                              Disabled="@(model.Apppoved==true)"
                                                              ImageUrl="@model.HealthCode"
                                                              Label="@L["Upload a health code"]"
                                                              PassCode="@model.PassCode"
                                                              OnUploaded="@(s=> model.HealthCode=s)"
                                                              Tag="H"></UploadPhotoComponent>
                                        <UploadPhotoComponent Desciption="@L["Make sure you haven't been to a medium-high risk area for 14 days"]"
                                                              Disabled="@(model.Apppoved==true)"
                                                              ImageUrl="@model.TripCode"
                                                              Label="@L["Upload a trip code"]"
                                                              PassCode="@model.PassCode"
                                                              OnUploaded="@(s=> model.TripCode=s)"
                                                              Tag="T"></UploadPhotoComponent>
                                        <UploadPhotoComponent Desciption="@L["Valid nucleic acid test report within 48 hours"]"
                                                              Disabled="@(model.Apppoved==true)"
                                                              ImageUrl="@model.NucleicAcidTestReport"
                                                              Label="@L["Upload a nucleic acid test report"]"
                                                              PassCode="@model.PassCode"
                                                              OnUploaded="@(s=> model.NucleicAcidTestReport=s)"
                                                              Tag="R"></UploadPhotoComponent>
                                    </div>

                                </div>
                            </MudItem>
                            <MudItem xs="12">
                                <CompanionComponent TRequest="model"></CompanionComponent>
                            </MudItem>
                            <MudItem xs="12" sm="6">
                                <MudCheckBox Label="@L["Agree Privacy Policy"]"
                                             For="@(() => model.PrivacyPolicy)"
                                             Disabled="@(model.Apppoved==true)"
                                             Required="true" RequiredError="You must agree"
                                             @bind-Checked="model.PrivacyPolicy"></MudCheckBox>
                            </MudItem>
                            <MudItem xs="12" sm="6">
                                <MudCheckBox Label="@L["I promise the truth"]"
                                             For="@(() => model.Promise)"
                                             Disabled="@(model.Apppoved==true)"
                                             Required="true" RequiredError="You must promise"
                                             @bind-Checked="model.Promise"></MudCheckBox>
                            </MudItem>
                        </MudGrid>
                    </MudForm>
                </MudPaper>
                <MudPaper Class="d-flex pa-4 mt-4">
                    <MudButton Variant="Variant.Filled"
                    Color="MudBlazor.Color.Secondary"
                    DisableElevation="true"
                    OnClick="Reset" Class="ml-auto mx-2">@L["Reset"]</MudButton>
                    <MudButton Variant="Variant.Filled"
                               Disabled="@(model.Id>0 || _submiting)"
                               DisableElevation="true"
                               OnClick="Submit">
                        @if (_submiting)
                        {
                            <MudProgressCircular Class="ms-n1" Size="MudBlazor.Size.Small" Indeterminate="true" />
                            <MudText Class="ms-2">@L["Processing"]</MudText>
                        }
                        else
                        {
                            <MudText>@L["Submit"]</MudText>
                        }
                    </MudButton>
                </MudPaper>
            </MudItem>
            <MudItem xs="12" sm="5">
                <MyPassCodeComponent @ref="myqrcode" Keyword="@_searchQRcode"></MyPassCodeComponent>
            </MudItem>
        </MudGrid>
    </ChildContent>
    <ErrorContent>
        <CustomError Exception="context"></CustomError>
    </ErrorContent>
</ErrorBoundary>
@code {
    private MyPassCodeComponent myqrcode;
    public string? Title { get; private set; }
    private MudForm form = default!;
    private string? _searchString = string.Empty;
    private string? _searchQRcode = string.Empty;
    private VisitorDto? _visitorDto = new();
    private VisitorDto? _visitorWithQRCode = new();
    private List<VisitorHistoryDto> _visitorHistories = new();
    public List<CompanionDto> _companionDtoList = new();
    private CreateVisitorCommandValidator modelValidator = new CreateVisitorCommandValidator();
    private CreateVisitorCommand model { get; set; } = new CreateVisitorCommand();
    private bool _notfound;
    private bool _loading;
    private bool _uploading;
    private bool _submiting;
    [Inject] private IUploadService _uploadService { get; set; } = default!;
    [Inject]
    private ISender _mediator { get; set; } = default!;
    [Inject]
    private Hashids hashids { get; set; } = default!;
    [CascadingParameter]
    protected Task<AuthenticationState> AuthState { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        Title = L["Pre Registers"];
        model.PassCode = hashids.EncodeLong(DateTime.Now.Ticks);
        var state = await AuthState;
    }
    private async Task OnSearch()
    {
        if (string.IsNullOrEmpty(_searchString)) _visitorDto = null;
        _visitorDto = await _mediator.Send(new SearchVisitorQuery(_searchString));
        if (_visitorDto != null)
        {
            if (_visitorDto.Apppoved != true && _visitorDto.CheckinDate is null)
            {
                model = new CreateVisitorCommand()
                    {
                        Id = _visitorDto.Id,
                        PassCode = _visitorDto.PassCode,
                        Name = _visitorDto.Name,
                        IdentificationNo = _visitorDto.IdentificationNo,
                        CompanyName = _visitorDto.CompanyName,
                        Address = _visitorDto.Address,
                        Avatar = _visitorDto.Avatar,
                        Email = _visitorDto.Email,
                        DesignationId = _visitorDto.DesignationId,
                        EmployeeId = _visitorDto.EmployeeId,
                        Gender = _visitorDto.Gender,
                        LicensePlateNumber = _visitorDto.LicensePlateNumber,
                        PhoneNumber = _visitorDto.PhoneNumber,
                        Purpose = _visitorDto.Purpose,
                        Apppoved = _visitorDto.Apppoved,
                        ApprovalOutcome = _visitorDto.ApprovalOutcome,
                        CheckinDate = _visitorDto.CheckinDate,
                        CheckoutDate = _visitorDto.CheckoutDate,
                        Comment = _visitorDto.Comment,
                        Designation = _visitorDto.Designation,
                        Companions = _visitorDto.Companions,
                        Employee = _visitorDto.Employee,
                        EmployeeDesignation = _visitorDto.EmployeeDesignation,
                        ExpectedDate = _visitorDto.ExpectedDate,
                        ExpectedTime = _visitorDto.ExpectedTime,
                        HealthCode = _visitorDto.HealthCode,
                        QrCode = _visitorDto.QrCode,
                        NucleicAcidTestReport = _visitorDto.NucleicAcidTestReport,
                        SiteId = _visitorDto.SiteId,
                        Status = _visitorDto.Status,
                        TripCode = _visitorDto.TripCode,
                        Promise = true,
                        PrivacyPolicy = true
                    };
            }
            else
            {
                model = new CreateVisitorCommand()
                    {
                        PassCode = hashids.EncodeLong(DateTime.Now.Ticks),
                        Name = _visitorDto.Name,
                        IdentificationNo = _visitorDto.IdentificationNo,
                        CompanyName = _visitorDto.CompanyName,
                        Address = _visitorDto.Address,
                        Avatar = _visitorDto.Avatar,
                        Email = _visitorDto.Email,
                        DesignationId = _visitorDto.DesignationId,
                        EmployeeId = _visitorDto.EmployeeId,
                        Gender = _visitorDto.Gender,
                        LicensePlateNumber = _visitorDto.LicensePlateNumber,
                        PhoneNumber = _visitorDto.PhoneNumber,
                        Purpose = _visitorDto.Purpose,
                        Promise = true,
                        PrivacyPolicy = true

                    };
            }
        }

    }
    private Task Reset()
    {


        model = new CreateVisitorCommand();
        model.PassCode = hashids.EncodeLong(DateTime.Now.Ticks);

        return Task.CompletedTask;
    }

    private async Task Submit()
    {
        _submiting = true;
        try
        {
            await form.Validate();
            if (form.IsValid)
            {
                var siteConfig = await _mediator.Send(new GetBySiteIdConfigurationsQuery(model.SiteId));
                if (model.Promise != true)
                {
                    Snackbar.Add(L["You must promise"], MudBlazor.Severity.Error);
                    return;
                }
                if (model.PrivacyPolicy != true)
                {
                    Snackbar.Add(L["You must agree"], MudBlazor.Severity.Error);
                    return;
                }
                if (string.IsNullOrEmpty(model.HealthCode) && (siteConfig is not null && siteConfig.MandatoryHealthQrCode))
                {
                    Snackbar.Add(L["You must upload health code"], MudBlazor.Severity.Error);
                    return;
                }
                if (string.IsNullOrEmpty(model.TripCode) && (siteConfig is not null && siteConfig.MandatoryTripCode))
                {
                    Snackbar.Add(L["You must upload trip code"], MudBlazor.Severity.Error);
                    return;
                }
                if (string.IsNullOrEmpty(model.NucleicAcidTestReport) && (siteConfig is not null && siteConfig.MandatoryNucleicAcidTestReport))
                {
                    Snackbar.Add(L["You must upload nucleic acid test report"], MudBlazor.Severity.Error);
                    return;
                }

                await this.generateQrCode();
                var result = await _mediator.Send(model);
                model.Id = result.Data;
                _submiting = true;
                _searchQRcode = model.PassCode;
                Snackbar.Add(L["Submit successfully"], MudBlazor.Severity.Info);
                await Reset();
                await Task.Delay(1000);
                StateHasChanged();
                await myqrcode.SearchQRcode();


            }
        }
        finally
        {
            _submiting = false;
        }
    }
    private async Task generateQrCode()
    {
        var qr = QrCode.EncodeText(model.PassCode, QrCode.Ecc.Medium);
        var qrcode = qr.ToPng(12, 4);
        var result = await _uploadService.UploadAsync(new UploadRequest()
            {
                Data = qrcode,
                FileName = "Q_" + Guid.NewGuid().ToString() + ".png",
                Extension = ".png",
                Folder = model.PassCode,
                UploadType = UploadType.VisitorPricture
            });
        model.QrCode = result.Replace("\\", "/");
    }

    }
